/**
 * 设置缓存值
 * @param key 主键
 * @param value 值
 * @param storageType 缓存类型，{1: sessionStorage , 2: localStorage }
 */
export function setStorage(key, value, storageType) {
  if (Object.prototype.toString.call(value) === '[object Object]' || Object.prototype.toString.call(value) === '[object Array]') {
    value = JSON.stringify(value);
  }
  if (!!storageType && storageType === 1) {
    sessionStorage.setItem(key, value);
  } else {
    localStorage.setItem(key, value);
  }
}

/**
 * 获取缓存
 * @param key 主键
 * @param storageType 缓存类型，{1: sessionStorage , 2: localStorage }
 * @param isJSON 是否返回JSON，{true: 返回JSON , false: 返回String }
 * @returns {*}
 */
export function getStorage(key, storageType, isJSON) {
  var value;
  if (!!storageType && storageType === 1) {
    value = sessionStorage.getItem(key);
  } else {
    value = localStorage.getItem(key);
  }
  if (!!isJSON) {
    try {
      value = JSON.parse(value);
    } catch (err) { }
  }
  return value;
}

/**
 * 删除缓存
 * @param key 主键
 * @param storageType 缓存类型，{1: sessionStorage , 2: localStorage }
 */
export function removeStorage(key, storageType) {
  if (!!storageType && storageType === 1) {
    sessionStorage.removeItem(key);
  } else {
    localStorage.removeItem(key);
  }
}

/**
 * 兼容性本地化存储方案封装
 * 调用:
 * new LocalData().set('xxx', 123)
 * new LocalData().get('xxx')
 * new LocalData().remove('xxx')
 */
export function LocalData() {
  this.isLocalStorage = !!window.sessionStorage; // 用于判断sessionStorage是否可用
  this.dataDom = null;
  /**
   * 当window.sessionStorage和window.localStorage不可用，则将数据存在dom节点
   * @param key 主键，由set()或get()方法传入
   * @returns {boolean}
   */
  this.initDom = (key) => {
    if (!this.dataDom) {
      try {
        this.dataDom = document.createElement('input'); // 这里使用hidden的input元素
        this.dataDom.type = 'hidden';
        this.dataDom.style.display = 'none';
        this.dataDom.setAttribute('id', key);
        document.body.appendChild(this.dataDom);
        return true;
      } catch (err) {
        return false;
      }
    } else {
      return true;
    }
  };
  /**
   * 存储
   * @param key 主键
   * @param value 值
   * @param storageType 缓存类型，{1: sessionStorage , 2: localStorage }, 默认为1
   */
  this.set = (key, value, storageType = 1) => {
    if (this.isLocalStorage) {
      setStorage(key, value, storageType);
    } else {
      if (this.initDom(key)) {
        if (Object.prototype.toString.call(value) === '[object Object]' || Object.prototype.toString.call(value) === '[object Array]') {
          value = JSON.stringify(value);
        }
        this.dataDom.value = value;
      }
    }
  };
  /**
   * 获取
   * @param key 主键
   * @param storageType 缓存类型，{1: sessionStorage , 2: localStorage }, 默认为1
   * @param isJSON 是否返回JSON，{true: 返回JSON , false: 返回String }, 默认为true
   * @returns {string | *}
   */
  this.get = (key, storageType = 1, isJSON = true) => {
    if (this.isLocalStorage) {
      return getStorage(key, storageType, isJSON);
    } else {
      if (this.initDom(key)) {
        var value = this.dataDom.value;
        if (isJSON) {
          try {
            value = JSON.parse(value);
          } catch (err) { }
        }
        return value;
      }
    }
  };
  /**
   * 删除存储
   * @param key 主键
   * @param storageType 缓存类型，{1: sessionStorage , 2: localStorage }
   */
  this.remove = (key, storageType) => {
    if (this.isLocalStorage) {
      removeStorage(key, storageType);
    } else {
      if (this.initDom(key)) {
        document.body.removeChild(this.dataDom);
        this.dataDom = null;
      }
    }
  };
}

/**
 * 设置cookie
 * @param c_name cookie名字
 * @param value cookie 值
 * @param expiremDays 设置过期时间
 */
export function setCookie(c_name, value, expiremDays) {
  var exdate = new Date();
  exdate.setTime(exdate.getTime() + expiremDays * 1000 * 60 * 60 * 24);
  document.cookie = c_name + "=" + escape(value) + ((expiremDays == null) ? "" : ";expires=" + exdate.toGMTString());
}

/**
 * 读取cookie
 * @param c_name cookie名字
 */
export function getCookie(c_name) {
  if (document.cookie.length > 0) {
    var c_start = document.cookie.indexOf(c_name + "=");
    if (c_start != -1) {
      c_start = c_start + c_name.length + 1;
      var c_end = document.cookie.indexOf(";", c_start);
      if (c_end == -1)
        c_end = document.cookie.length
      return unescape(document.cookie.substring(c_start, c_end))
    }
  }
  return ""
}

/**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              y'y'y'y'y'y'y'y'y'y'y'y'y'y'y'y'y'y'y'y'y'y'y'y'y'y'y'y'y'y'y'y'y'y'y'y'y'y'y'y'y'y'y'y'y'y'y'y'y'y'y'y'y'y'y'y'y'y'y'y'y'y'y
 * @param c_name cookie名字
 */
export function delCookie(c_name) {
  var exp = new Date();
  exp.setTime(exp.getTime() - 1);
  var cval = this.getCookie(c_name);
  if (cval != null) {
    document.cookie = c_name + "=" + cval + ";expires=" + exp.toGMTString();
  }
}

/**
 * 事件绑定
 * @param {*} ele  [当前的dom对象]
 * @param {*} type  [当前的事件类型]
 * @param {*} callback [当前的回调方法]
 */
export function addEventListeners(ele, type, callback) {
  if (ele.addEventListener) {
    ele.addEventListener(type, callback, false);
  } else if (ele.attachEvent) {
    ele.attachEvent('on' + type, callback);
  } else {
    ele['on' + type] = callback;
  }
}

/**
 * 事件解绑
 * @param {any} el [当前的dom对象]
 * @param {any} event [当前的事件]
 * @param {any} fn [当前的事件方法]
 */
export function eventsOff(el, event, fn) {
  if (el.removeEventListener) {
    el.removeEventListener(event, fn, false);
  } else if (el.detachEvent) {
    el.detachEvent('on' + event, fn.bind(el));
  } else {
    el['on' + event] = null;
  }
}

/**
 * 截取url参数
 * @param {*} variable 
 */
export function getQueryVariable(variable) {
  if (!window.location.search) { return false; }
  var query = window.location.search.substring(1);
  var vars = query.split("&");
  for (var i = 0; i < vars.length; i++) {
    var pair = vars[i].split("=");
    if (pair[0] == variable) {
      return pair[1];
    }
  }
  return false;
}

/**
 * 截取URL地址某个参数的值
 * @param {*} name 【name 某个参数name】
 * @returns 
 */
export function getQueryStringByName(name) {
  var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
  var r = window.location.search.substr(1).match(reg);
  var context = "";
  if (r != null)
    context = r[2];
  reg = null;
  r = null;
  return context == null || context == "" || context == "undefined" ? "" : context;
}

/**
 * 伪数组转为真实数组
 * @param {*} list 伪数组
 * @param {*} start 开始索引
 * @returns 
 */
export function toArray (list, start) {
  start = start || 0;
  let i = list.length - start;
  let ret = new Array(i);
  while (i--) {
    ret[i] = list[i + start];
  }
  return ret
}

/**
 * 判定为对象
 * @param {*} obj 
 * @returns 
 */
 export function isObject(obj) {
  return obj !== null && typeof obj === 'object'
}

/**
 * 判断两个值是否相等 包括基本类型、复合类型
 * @param {*} a 
 * @param {*} b 
 * @returns 
 */
export function looseEqual (a, b) {
  if (a === b) { return true }
  var isObjectA = isObject(a);
  var isObjectB = isObject(b);
  if (isObjectA && isObjectB) {
    try {
      var isArrayA = Array.isArray(a);
      var isArrayB = Array.isArray(b);
      if (isArrayA && isArrayB) {
        return a.length === b.length && a.every(function (e, i) {
          return looseEqual(e, b[i])
        })
      } else if (a instanceof Date && b instanceof Date) {
        return a.getTime() === b.getTime()
      } else if (!isArrayA && !isArrayB) {
        var keysA = Object.keys(a);
        var keysB = Object.keys(b);
        return keysA.length === keysB.length && keysA.every(function (key) {
          return looseEqual(a[key], b[key])
        })
      } else {
        /* istanbul ignore next */
        return false
      }
    } catch (e) {
      /* istanbul ignore next */
      return false
    }
  } else if (!isObjectA && !isObjectB) {
    return String(a) === String(b)
  } else {
    return false
  }
}